<?php 
namespace Cyfy;

/**
 * Setup class for modules.
 *
 * Standart setup class for modules, therefore, they can have their own setup class derived from this.
 *
 * @category cyfy
 * @author Dandelion <dandelion8888@gmail.com>
 * @version 0.1
 */
class ModuleSetup extends \Cyfy\Translatable
{
    /**
     * Module information in associative array.
     * @var array
     */
    static public $info = array(); 
     
    /**
     * Changes module state.
     *
     * @param string Module name
     * @param string One of the possible options: install, install-run, enable, disable, uninstall, reinstall.
     */
    final static function changeState($do)
    {
        if(!count(self :: $info))
        {
            return false;
        }
        
        $setupClass = get_called_class();
        $parentClass = __CLASS__;
        
        switch($do)
        {
            case "uninstall":
            
               if(!$setupClass :: preDisable()) return false;
               
                $setupClass :: disable();
                $setupClass :: preUninstall();
                $setupClass :: uninstall();
                \Cyfy\Message :: set($parentClass :: t(41, self :: $info['name']), \Cyfy\Message::WARNING);
                break;
            
            case "reinstall":
                $setupClass :: preDisable();
                $setupClass :: disable();
                $setupClass :: preUninstall();
                $setupClass :: uninstall();
                $setupClass :: preInstall();
                $setupClass :: install();
                $setupClass :: enable();				
                $setupClass :: postEnable();
                \Cyfy\Message :: set($parentClass :: t(51, self :: $info['name']));
                break;
            
            case "install":
            
                if(!$setupClass :: preInstall()) return false;
                $setupClass :: install();
                \Cyfy\Message :: set($parentClass :: t(11, self :: $info['name']));
                break;
                
            case "install-run":
            
                if(!$setupClass :: preInstall()) return false;
                
                $setupClass :: install();
                $setupClass :: enable();
                $setupClass :: postEnable();
                \Cyfy\Message :: set($parentClass :: t(11, self :: $info['name']));
                \Cyfy\Message :: set($parentClass :: t(21, self :: $info['name']));
                break;
                
            case "enable":
                $setupClass :: enable();
                $setupClass :: postEnable();
                \Cyfy\Message :: set($parentClass :: t(21, self :: $info['name']));
                break;
             
            case "disable":

                if(!$setupClass :: preDisable()) return false;
                
                $setupClass :: disable();
                \Cyfy\Message :: set($parentClass :: t(31, self :: $info['name']), \Cyfy\Message::WARNING);
                break;
        }
        return true;
    }
  
  
    /**
     * Performs pre-install actions.
     */
    static function preInstall()
    {
        // checks the depedencies before install
        if(!\Cyfy\Modules\Modules\Module :: checkDependenciesWhenInstalling(self :: $info)){
            \Cyfy\Log :: writeError('Dependencies fail when installing: ' . self :: $info['name']);
            return false;
        }
        
         // create filesystem, if not possible -> false
        if(!\Cyfy\Modules\Modules\Module :: createFilesystemFromXML(self :: $info['classname']))
        {
            \Cyfy\Log :: writeError('Filesystem fail when installing: ' . self :: $info['name']);
            return false;
        }
        
        // CREATE DB
        \Cyfy\Modules\Modules\Module :: createTablesFromXML(self :: $info['classname']);
        
        // insert into modules
        $info = array(
            'name' => self :: $info['classname'],
            'state' => 1
        );
        \dibi :: query("INSERT INTO [:cyfy:Modules] %v", $info);
        
        return true;
    }
    
    /**
     * Dummy method.
     */
    static function install(){}
  
    /**
     * Performs enable in DB.
     */
    static function postEnable()
    {
        \dibi :: query("UPDATE [:cyfy:Modules] SET [state] = 2 WHERE [name] = %s", self :: $info['classname']);
        
        // always load?
        if(file_exists('Cyfy/Modules/' . self :: $info['classname'] . '/Module.php')){
            $classname = '\Cyfy\Modules\\' . self :: $info['classname'] . '\Module';
            if(method_exists($classname, 'start') || method_exists($classname, 'end'))
            {
                \dibi :: query("UPDATE [:cyfy:Modules] SET [always] = 1 WHERE [name] = %s", self :: $info['classname']);
            }
        }
        
        return true;
    }
    
    /**
     * Dummy method.
     */
    static function enable(){}
  
    /**
     * Checks depedencies and after disables the module.
     */
    static function preDisable()
    {
        // checks the depedencies
        if(!\Cyfy\Modules\Modules\Module :: checkDependenciesWhenDisabling(self :: $info['classname'])) return false;
        
        // update modules set state 1
        \dibi :: query("UPDATE [:cyfy:Modules] SET [state] = 1 WHERE [name] = %s", self :: $info['classname']);

        // always to 0
        \dibi :: query("UPDATE [:cyfy:Modules] SET [always] = 0 WHERE [name] = %s", self :: $info['classname']);
        
                
        // remove filesystem
        \Cyfy\Cyfy :: unregisterPathByModule(self :: $info["classname"]);
        
        return true;
    }
    
    /**
     * Dummy method.
     */
    static function disable(){}

    /**
     * Removes all data from DB, permissions and virtual system entries.
     */
    static function preUninstall()
    {
        // delete from modules...
        \dibi :: query("DELETE FROM [:cyfy:Modules] WHERE [name] = %s", self :: $info['classname']);
        
        // drops tables
        \Cyfy\Modules\Modules\Module :: dropTablesFromXML(self :: $info["classname"]);
        
        // deletes constants
        \dibi :: query("DELETE FROM [:cyfy:Cyfy-constants] WHERE [module] = %s", self :: $info["classname"]);

        return true;
    }
    
    /**
     * Dummy method.
     */
    static function uninstall(){}

}
